#include "../include/CloudSvr.h"


#define DFPORT 33333
using asio::ip::udp;
int max_length = 1024;
CCloudSvr::CCloudSvr()
{
    m_nPort = DFPORT;
    m_pSocket = NULL;
    //ctor
}

CCloudSvr::~CCloudSvr()
{
    //dtor
}

void CCloudSvr::SetPort(int port)
{
    m_nPort = port;
}


void CCloudSvr::begin()
{
    if(!m_pSocket)
    {
        m_pSocket = new udp::socket(io_context, udp::endpoint(udp::v4(), m_nPort));
        char data[max_length];
        udp::endpoint sender_endpoint;
        while(true){
            size_t length = m_pSocket->receive_from(asio::buffer(data, max_length), sender_endpoint);
            if(length <= 0){
                return;
            }

            //data[0] = -data[0];
            MSGHeader *pHeader = (MSGHeader*)data;
            char ctype = pHeader->type;
            //pHeader->type = -ctype;
            char *pBody = data + sizeof(MSGHeader);
            if(ctype == 1){ //heart beat
                BT *pHB = (BT*)data;
                IPInfo info;
                info.addr = sender_endpoint;
                mapForIP[pHB->id] = info;
                //data[0] = -1;
                //data[1] = pHB->header.seq;
                pHeader->type = -1;
                m_pSocket->send_to(asio::buffer(data,sizeof(MSGHeader)),sender_endpoint);
            }
            else if(ctype == 2){//wakeup
                BT *pHB = (BT*)data;
                std::map<std::string,IPInfo>::iterator pos = mapForIP.find(pHB->id);
               // data[0] = -2;
                if(pos != mapForIP.end()){
                    pHeader->type = 3;
                    std::string ip = pos->second.addr.address().to_string();
                    int len = sprintf(pBody,"%s:%d",ip.c_str(),pos->second.addr.port());
                    m_pSocket->send_to(asio::buffer(data,len + sizeof(MSGHeader)),sender_endpoint); //tell target ip and port

                    len = sprintf(pBody,"%s:%d",sender_endpoint.address().to_string().c_str(),sender_endpoint.port());
                    udp::endpoint targetAddr(asio::ip::address_v4::from_string(ip),pos->second.addr.port());

                    m_pSocket->send_to(asio::buffer(data,len + sizeof(MSGHeader)),targetAddr); //send to target begin try to connect
                }
                else{
                    int len = sprintf(pBody,"error:not found");
                    m_pSocket->send_to(asio::buffer(data,len + sizeof(MSGHeader)),sender_endpoint);
                }
            }
        }

    }

}

